/*
 * Copyright 2003 Program of Computer Graphics, Cornell University
 *     580 Rhodes Hall
 *     Cornell University
 *     Ithaca NY 14853
 * Web: http://www.graphics.cornell.edu/
 * 
 * Not for commercial use. Do not redistribute without permission.
 */

#ifndef _H_PRIMITIVELIST
#define _H_PRIMITIVELIST

#include "KDSplits.h"
#include "PoolAllocator.h"
#include <memory.h>

#ifdef USE_COMPILED_SHARED_TRIANGLE
//we special case lists of quad packed triangles and store them with the usual
//PrimitiveList header (since they are by far the most common case, this saves memory)
//to make this possible we store two bits of information in the first triangle
//pointer in each quad packed triangle object.  The compiled triangles are 16byte
//aligned so the bottom 4 bits can be used (two for KDST_LEAF and two below)
//NB: only used if USE_COMPILED_SHARED_TRIANGLE is set
#define PL_QUADPACKEDTRIANGLE                0x04
#define PL_QUADPACKEDTRIANGLE_END            0x08
#define PL_QUADPACKEDTRIANGLE_POINTER_MASK   (~0x0F)

#endif //USE_COMPILED_SHARED_TRIANGLE

//function to test some primitives for intersection with a ray
//we allow custom primitives though quad-packed triangles are the default
typedef void (*IntersectPrimitiveList)(class PrimitiveList *, class Ray *ray, class IntersectionRecord *);

//abstract base class for primtive lists
class ALIGN16 PrimitiveList {
private:
  int typeIdBits; //indicates type of primitive, must also have low bits set to KDST_LEAF
                  //and not be a denormal if loaded as a float or SplitCode
protected:
  void setType(int type) { typeIdBits = 0x40000000|KDST_LEAF|((type&0x0FFFF)<<8); }
public:
  IntersectPrimitiveList func; //null for default (quad-packed triangles)
  class PrimitiveList *next;
  int length;

  int getType() { return (typeIdBits>>8)&0x0FFFF; }

#ifdef USE_COMPILED_SHARED_TRIANGLE

  int isQuadPackedTriangleList() { return typeIdBits&PL_QUADPACKEDTRIANGLE; }

#else //USE_COMPILED_SHARED_TRIANGLE

  int isQuadPackedTriangleList() { return func==NULL; }

#endif //USE_COMPILED_SHARED_TRIANGLE

};


#endif //_H_PRIMITIVELIST

